package com.sh.data.engine.domain.normalization.modeldesign.cdm.service;

import com.baomidou.mybatisplus.extension.service.IService;
import com.sh.data.engine.domain.normalization.modeldesign.cdm.model.domain.TblRelationDomain;
import com.sh.data.engine.domain.normalization.modeldesign.cdm.model.param.TblRelationParam;
import com.sh.data.engine.domain.normalization.modeldesign.cdm.model.param.TblRelationRemoveParam;
import com.sh.data.engine.domain.normalization.modeldesign.model.model.param.SaveModelParam;
import com.sh.data.engine.repository.dao.normalization.modeldesign.cdm.entity.TblRelationEntity;

import java.util.List;

public interface TblRelationService extends IService<TblRelationEntity> {

    /**
     * 根据项目id和主表id，向右查询出所有关联关系
     *
     * @param projectId   项目id
     * @param mainTableId 主表id
     * @return 关联关系集合
     */
    List<TblRelationDomain> getRelListLeftForward(Long projectId, Long mainTableId);

    /**
     * 根据项目id和关联表id，向左查询出所有关联关系
     *
     * @param projectId   项目id
     * @param mainTableId 关联表id
     * @return 关联关系集合
     */
    List<TblRelationDomain> getRelListRightForward(Long projectId, Long mainTableId);

    /**
     * 按外表查询
     *
     * @param projectId         项目id
     * @param foreignTableId    外表id
     * @param foreignTableField 外表字段
     * @return 集合
     */
    List<TblRelationDomain> selectByForeign(
        Long projectId, Long foreignTableId, String foreignTableField);

    /**
     * 删除主表到外表的关联关系
     *
     * @param projectId      项目id
     * @param mainTableId    主表id
     * @param foreignTableId 外表id
     * @return 删除数量
     */
    boolean deleteByTable(Long projectId, Long mainTableId, Long foreignTableId);

    /**
     * 删除主表字段到外表字段的关联关系
     *
     * @param projectId         项目id
     * @param mainTableId       主表id
     * @param mainTableField    主表字段
     * @param foreignTableId    外表id
     * @param foreignTableField 外表字段
     * @return 删除数量
     */
    boolean deleteByTableField(
        Long projectId,
        Long mainTableId,
        String mainTableField,
        Long foreignTableId,
        String foreignTableField);

    // 修改表结构的时候同步刷新表关联关系
    boolean refreshTblRelation(SaveModelParam saveModelParam);

    /**
     * 根据主表id查询
     *
     * @param mainTblId
     * @return
     */
    List<TblRelationDomain> getByMainTblId(Long mainTblId);

    /**
     * 根据外表id查询
     *
     * @param foreignTblId
     * @return
     */
    List<TblRelationDomain> getByForeignTblId(Long foreignTblId);

    /**
     * 根据ids查列表
     *
     * @param ids
     * @return
     */
    List<TblRelationDomain> getListByIds(List<Long> ids);

    // 修改表结构的时候更新关联关系的表字段
    void updateFieldName(Long tblId, String oldField, String newField);

    /**
     * 根据项目id和表id，查询出所有关联关系
     *
     * @param projectId 项目id
     * @param tableId   表id
     * @return 关联关系集合
     */
    List<TblRelationDomain> getDiagramTblRelationList(Long projectId, Long tableId);

    long countTblRelation(Long projectId, Long tblId);

    /**
     * 根据关联关系集合，插入关联表，拒绝重复
     *
     * @param relationList 关联关系
     * @return 插入数量
     */
    boolean saveTblRelation(List<TblRelationParam> relationList);

    public List<TblRelationEntity> listTblRelation(Long projectId, List<Long> tblIds);

    /**
     * 查找主表是否能有路径关联到外表 预测结果应该与根节点不会很远，广度优先
     *
     * @param projectId      项目id
     * @param mainTableId    主表id
     * @param foreignTableId 外表id
     * @return 第一次遇到的，主表通往外表的路径
     */
    List<String> theWayFromMainTableToForeignTable(
        Long projectId, Long mainTableId, Long foreignTableId);

    /**
     * 取消关系
     *
     * @param relation 关系集合
     * @return 删除数量
     */
    boolean deleteDiagramTblRelation(TblRelationRemoveParam relation);

    List<TblRelationDomain> getTblRelationList(Long tableId);
}
